﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using LoanMonitor.Business;
using TCKQKL.FrontEnd.DataModel;
using StockTrader.FrontEnd.DataContract;
using StockTrader.BusinessService.DataContract.Mortgate;
using Mortgage.DDL;
using Mortgage.DAL;

namespace LoanMonitor
{
    public partial class AssestEstimate : Form
    {
        private DALclient client = new DALclient();
        public AssestEstimate()
        {
            this.Font = SystemFonts.MessageBoxFont;
            InitializeComponent();
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            try
            {
                decimal investorID = client.getAccountData(txtAccountNo.Text).investorId;
                List<DateTime> backdate = client.getBackDate();
                List<InvestorDataUI> assignedAccounts = new List<InvestorDataUI>();
                bool isClearing = client.isClearingDone();

                decimal stockValue = 0;
                decimal cashValue = 0;
                decimal assetValue = 0;
                decimal t2needed = 0;
                decimal cashneeded = 0;

                if (isClearing)
                {
                    lblBoscState.Text = "Đã kết thúc ngày";
                    lblAssetAmount.BackColor = Color.PaleGreen;
                    lblT1.Text = "Ngày T-1 (" + backdate[1].ToString("dd/MM/yyyy") + ")";
                    tbT0.Text = "Ngày T-1 (" + backdate[1].ToString("dd/MM/yyyy") + ")";
                    lblT2.Text = "Ngày T-2 (" + backdate[2].ToString("dd/MM/yyyy") + ")";
                    tbT1.Text = "Ngày T-2 (" + backdate[2].ToString("dd/MM/yyyy") + ")";
                    lblT3.Text = "Ngày T-3 (" + backdate[3].ToString("dd/MM/yyyy") + ")";
                    tbT2.Text = "Ngày T-3 (" + backdate[3].ToString("dd/MM/yyyy") + ")";
                }
                else
                {
                    lblBoscState.Text = "Đang giao dịch";
                    lblAssetAmount.BackColor = SystemColors.Control;
                    lblT1.Text = "Ngày T-1 (" + backdate[0].ToString("dd/MM/yyyy") + ")";
                    tbT0.Text = "Ngày T-1 (" + backdate[0].ToString("dd/MM/yyyy") + ")";
                    lblT2.Text = "Ngày T-2 (" + backdate[1].ToString("dd/MM/yyyy") + ")";
                    tbT1.Text = "Ngày T-2 (" + backdate[1].ToString("dd/MM/yyyy") + ")";
                    lblT3.Text = "Ngày T-3 (" + backdate[2].ToString("dd/MM/yyyy") + ")";
                    tbT2.Text = "Ngày T-3 (" + backdate[2].ToString("dd/MM/yyyy") + ")";
                }

                if (chkIncludeAssigned.Checked)
                    assignedAccounts = client.getAssignAccountsByInvestorId(investorID);

                for (int i = grpAccountList.Controls.Count - 1; i >= 0; i--)
                    grpAccountList.Controls.Remove(grpAccountList.Controls[i]);

                for (int j = 0; j < assignedAccounts.Count; j++)
                {
                    AssetUI bHouse = getAssetInfoByAccountNo(assignedAccounts[j].accountNo);
                    stockValue += bHouse.StockAmount;
                    cashValue += bHouse.CashAmount;
                    assetValue += bHouse.AssetAmount;
                    t2needed += bHouse.TotalT2Needed;
                    cashneeded += bHouse.TotalCashNeeded;

                    UpdateUIWithAssignAccount(assignedAccounts[j].accountNo, j);
                }

                AssetUI mainHouse = getAssetInfoByAccountNo(txtAccountNo.Text);
                stockValue += mainHouse.StockAmount;
                cashValue += mainHouse.CashAmount;
                assetValue += mainHouse.AssetAmount;
                t2needed += mainHouse.TotalT2Needed;
                cashneeded += mainHouse.TotalCashNeeded;

                UpdateAssetUI(mainHouse);

                Button mainAccount = new Button();
                mainAccount.BackColor = Color.PaleGreen;
                mainAccount.Width = 80;
                mainAccount.Location = new Point(5, 17);
                mainAccount.Text = txtAccountNo.Text;
                mainAccount.Click += new EventHandler(UpdateInfo);
                grpAccountList.Controls.Add(mainAccount);
                mainAccount.Focus();

                lblStocksValue.Text = stockValue.ToString("N0");
                lblCashValue.Text = cashValue.ToString("N0");
                lblAssetValue.Text = assetValue.ToString("N0");
                lblTotalT2Needed.Text = t2needed.ToString("N0");
                lblTotalCashNeeded.Text = cashneeded.ToString("N0");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + ". Kiểm tra lại số TK");
            }
        }

        private void UpdateInfo(object sender, EventArgs e)
        {
            for (int i = grpAccountList.Controls.Count - 1; i >= 0; i--)
                grpAccountList.Controls[i].BackColor = DefaultBackColor;

            Button investor = (Button)sender;
            AssetUI bHouse = getAssetInfoByAccountNo(investor.Text);
            investor.BackColor = Color.PaleGreen;
            UpdateAssetUI(bHouse);
        }

        private AssetUI getAssetInfoByAccountNo(string AccountNo)
        {
            AssetUI asset = new AssetUI();
            DALclient client = new DALclient();

            try
            {
                #region  Definitions
                List<TransDataUI> trans = new List<TransDataUI>();
                List<StocksData> PortfolioHolding = new List<StocksData>();
                List<BankDataUI> cash = new List<BankDataUI>();
                List<DateTime> backdate = new List<DateTime>();
                List<TradingResultUI> tr = new List<TradingResultUI>();
                List<AccountDataUI> hold = new List<AccountDataUI>();

                List<OrderUI> AllCustomerOrders = new List<OrderUI>();
                List<OrderUI> CustormerOrders = new List<OrderUI>();
                List<OrderUI> HoOrders = new List<OrderUI>();
                List<OrderUI> HaOrders = new List<OrderUI>();

                List<StocksData> T1holding = new List<StocksData>();
                List<StocksData> T2holding = new List<StocksData>();
                List<StocksData> T3holding = new List<StocksData>();


                Filter flt = new Filter();

                bool isClearing;

                #endregion

                #region  Share Objects
                decimal investorID = client.getAccountData(AccountNo).investorId;
                backdate = client.getBackDate();
                isClearing = client.isClearingDone();
                bool isDiscount = chkIsDiscount.Checked;
                bool isAvg = chkIsAvg.Checked;
                bool isCountSettlement = chkIsCountSettlement.Checked;
                bool isTradingOnly = chkIsTradingOnly.Checked;
                #endregion

                #region Cash
                cash = client.getBankDataByInvestorId(investorID);
                asset.PreLoan = client.getPreLoanByInvestor(investorID);
                #endregion

                #region Stocks

                #region T0

                #region Get all today orders
                HoOrders = client.getHoseOrders();
                HaOrders = client.getHastcOrders();
                AllCustomerOrders = MergeOrders(HaOrders, HoOrders);
                #endregion

                asset.T0TradingHist = flt.ordersFilter(AllCustomerOrders, AccountNo, string.Empty, string.Empty);
                if (isClearing)
                    AllCustomerOrders = null;
                else
                    if (AllCustomerOrders.Count.Equals(0))
                        tr = client.getTradingResultHistory(
                            investorID, DateTime.Today, DateTime.Today, string.Empty, string.Empty,
                            "SELL", string.Empty, string.Empty, 0, 99999999, 0, 99999999);
                //Hiển thị danh sách lệnh của khách hàng
                CustormerOrders = flt.ordersFilter(AllCustomerOrders, AccountNo, string.Empty, string.Empty);
                asset.T0Trading = CustormerOrders;

                //01. Hoạch toán luôn phần tiền đã bán được vào tiền chờ về
                if (!chkIntraday.Checked)
                {
                    //Tính số tiền đã bán được
                    asset.SoldAmount = flt.getNettingAmount(CustormerOrders);
                    asset.NettingAmount += asset.SoldAmount;
                }

                foreach (OrderUI order in CustormerOrders)
                {
                    if (order.Side.Equals("MUA"))
                    {
                        QuoteDataUI quote = client.getQuoteAvg(order.Symbol, isAvg);

                        //02. Giải tỏa tiền cho phần chứng khoán đã mua nhưng chưa khớp
                        //    chuyển từ phần đã phong tỏa sang giao dịch
                        if (!chkIntraday.Checked)
                        {
                            asset.TradingAmount += (order.Volume - order.MVolume) * quote.Ref * 1000;
                            asset.BlockAmount -= (order.Volume - order.MVolume) * quote.Ref * 1000;
                        }

                        //02. Tính lại giá trị ck mua vừa khớp với thời gian chờ về T+3
                        decimal amplitude = 0;//(quote.ExCenter.Equals("HOSE")) ? 0.05m : 0.07m;
                        if (quote.ExCenter.Equals("HOSE"))
                            amplitude = 0.05m;
                        else if (quote.ExCenter.Equals("HNX"))
                            amplitude = 0.07m;
                        else
                            amplitude = 0.1m;

                        if (isDiscount)
                            asset.T0BoughtStockValue += order.MVolume * estimateFutureValue(quote.Ref, amplitude, 3) * 1000;
                        else
                            asset.T0BoughtStockValue += order.MVolume * estimateFutureValue(quote.Ref, amplitude, 0) * 1000;
                    }
                }
                asset.BoughtAmount += flt.getSpentAmount(CustormerOrders);

                #endregion

                //Tra cứu danh mục đầu tư
                hold = client.getAccountByInvestorId(investorID);
                foreach (AccountDataUI stock in hold)
                {
                    long quantity = Convert.ToInt64(stock.tradingAmount);
                    QuoteDataUI quote = client.getQuoteAvg(stock.stockId, isAvg);
                    MortgageMornitorDAL dal = new MortgageMornitorDAL();
                    decimal rate = dal.getLoanRate(DateTime.Today, stock.stockId);

                    if ((CustormerOrders.Count.Equals(0)) && (tr.Count > 0))
                    {
                        foreach (TradingResultUI order in tr)
                            if (order.Symbol.Equals(quote.Symbol) && order.Side.Equals("Bán"))
                            {
                                //Trước giờ giao dịch (chưa có danh sách lệnh trả về từ TTGD) nếu đặt lệnh bán
                                //Tất cả lệnh bán coi như sẽ không khớp và chuyển chuyển trả lại phần CK đó vào số dư giao dịch
                                quantity += Convert.ToInt64(order.RootOrder.quantity);
                            }
                    }
                    else
                    {
                        //01. Chuyển phần chứng khoán bán nhưng chưa khớp vào số dư giao dịch
                        if (chkIntraday.Checked)
                            quantity += flt.getSellQttyBySymbol(CustormerOrders,
                                                              txtAccountNo.Text, quote.Symbol);
                        else
                            quantity += flt.getRemainSellQttyBySymbol(CustormerOrders,
                                                                  txtAccountNo.Text, quote.Symbol);
                    }
                    PortfolioHolding.Add(new StocksData(quote.Symbol, quantity, quote.Ref, 0, rate, quote.CompanyName));
                }
                asset.T0 = PortfolioHolding;
                asset.PorfolioTradingStockValue = getPortfolioValue(PortfolioHolding, isDiscount, isAvg);

                //Tra cứu thông tin thanh toán bù trừ


                if (!isClearing)
                {
                    T1holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[1]), 3, isCountSettlement, isAvg);
                    T2holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[2]), 2, isCountSettlement, isAvg);
                    T3holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[3]), 1, isCountSettlement, isAvg);
                }
                else
                {
                    T1holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[0]), 3, isCountSettlement, isAvg);
                    T2holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[1]), 2, isCountSettlement, isAvg);
                    T3holding = ConvertToStocksUI(client.getStockNettingInvestorId(
                                                        investorID, backdate[2]), 1, isCountSettlement, isAvg);

                }

                asset.T1BoughtStockValue = getPortfolioValue(T1holding, isDiscount, isAvg);
                asset.T1 = T1holding;
                asset.T2BoughtStockValue = getPortfolioValue(T2holding, isDiscount, isAvg);
                asset.T2 = T2holding;
                asset.T3BoughtStockValue = getPortfolioValue(T3holding, isDiscount, isAvg);
                asset.T3 = T3holding;


                #endregion

                if (isTradingOnly)
                    asset.StockAmount = asset.PorfolioTradingStockValue;
                else
                    asset.StockAmount += asset.PorfolioTradingStockValue
                                        + asset.T0BoughtStockValue
                                        + asset.T1BoughtStockValue
                                        + asset.T2BoughtStockValue
                                        + asset.T3BoughtStockValue;
                asset.TradingAmount += cash[0].tradingAmount;
                asset.NettingAmount += cash[0].nettingAmount;
                asset.BlockAmount += cash[0].blockAmount;
                asset.CashAmount = asset.NettingAmount + cash[0].tradingAmount - asset.PreLoan;
                asset.AssetAmount = asset.StockAmount +
                                    asset.NettingAmount +
                                    asset.TradingAmount -
                                    asset.PreLoan;

                asset.TotalT2Needed = asset.TradingAmount + flt.getSpentAmount(asset.T0TradingHist);
                asset.TotalCashNeeded = asset.TotalT2Needed + asset.NettingAmount - asset.PreLoan;

                return asset;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return asset;
            }
        }

        private void SendStocksUIToGrid(DataGridView grv, List<StocksData> holding)
        {
            grv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            grv.RowHeadersVisible = false;
            grv.DataSource = holding;

            if (holding.Count > 0)
            {
                grv.Columns["Symbol"].DisplayIndex = 0;
                grv.Columns["Quantity"].DisplayIndex = 1;
                grv.Columns["Ref"].DisplayIndex = 2;
                grv.Columns["Value"].DisplayIndex = 3;
                grv.Columns["Name"].DisplayIndex = 4;

                grv.Columns["Symbol"].HeaderText = "MCK";
                grv.Columns["Quantity"].HeaderText = "KL";
                grv.Columns["Ref"].HeaderText = "Giá TC";
                grv.Columns["Value"].HeaderText = "Giá trị";
                grv.Columns["Name"].HeaderText = "Tên cty";
                grv.Columns["TillSettlement"].HeaderText = "Ngày về";
                grv.Columns["AllowRate"].HeaderText = "Tỷ lệ cho vay";

                grv.Columns["Quantity"].DefaultCellStyle.Format = "N0";
                grv.Columns["Value"].DefaultCellStyle.Format = "N0";
                grv.Columns["Name"].Visible = false;
            }
        }

        private List<OrderUI> MergeOrders(List<OrderUI> orders1, List<OrderUI> orders2)
        {
            try
            {
                List<OrderUI> mergedlist = new List<OrderUI>();
                mergedlist.AddRange(orders1);
                mergedlist.AddRange(orders2);
                return mergedlist;
            }
            catch (System.Exception e)
            {
                throw e;
            }
        }

        private void setOrderSummaryGridLayout(DataGridView grv)
        {
            grv.Columns["Symbol"].HeaderText = "MCK";
            grv.Columns["Symbol"].DisplayIndex = 1;

            grv.Columns["Volume"].HeaderText = "KL đặt";
            grv.Columns["Volume"].DisplayIndex = 2;
            grv.Columns["Volume"].DefaultCellStyle.Format = "N0";

            grv.Columns["MVolume"].HeaderText = "KL khớp";
            grv.Columns["MVolume"].DisplayIndex = 3;
            grv.Columns["MVolume"].DefaultCellStyle.Format = "N0";

            grv.Columns["Status"].HeaderText = "Trạng thái";
            grv.Columns["Status"].DisplayIndex = 4;

            grv.Columns["MValue"].HeaderText = "Giá trị";
            grv.Columns["MValue"].DisplayIndex = 5;
            grv.Columns["MValue"].DefaultCellStyle.Format = "N0";


            grv.Columns["Time"].HeaderText = "Thời gian";
            grv.Columns["Time"].DisplayIndex = 6;

            grv.Columns["Side"].HeaderText = "Loại lệnh";
            grv.Columns["Side"].DisplayIndex = 7;

            grv.Columns["Price"].HeaderText = "Giá";
            grv.Columns["Price"].DisplayIndex = 8;

            grv.Columns["PriceChange"].HeaderText = "Sửa giá";
            grv.Columns["PriceChange"].DisplayIndex = 9;

            grv.Columns["AveragePrice"].HeaderText = "Giá TB";
            grv.Columns["AveragePrice"].DisplayIndex = 10;
            grv.Columns["AveragePrice"].DefaultCellStyle.Format = "N1";


            grv.Columns["AccountNo"].HeaderText = "Tài khoản";
            grv.Columns["AccountNo"].DisplayIndex = 11;

            grv.Columns["Market"].HeaderText = "Sàn";
            grv.Columns["Market"].DisplayIndex = 12;

            grv.Columns["AccountNoChange"].Visible = false;
            grv.Columns["CancelDetail"].Visible = false;
            grv.Columns["TransDate"].Visible = true;
            grv.Columns["OrderNo"].Visible = false;
            grv.Columns["PriceChange"].Visible = false;
            grv.Columns["AveragePrice"].Visible = false;
            grv.Columns["AccountNo"].Visible = false;
            grv.Columns["TransDate"].Visible = false;

            //             grvOrders.Columns["AccountNoChange"].HeaderText = "Sửa TK";
            //             grvOrders.Columns["AccountNoChange"].DisplayIndex = 12;

        }

        private decimal getPortfolioValue(List<StocksData> list, bool isDiscount, bool isAvg)
        {
            decimal stockvalue = 0;

            DALclient client = new DALclient();
            foreach (StocksData item in list)
            {
                QuoteDataUI quote = client.getQuoteAvg(item.Symbol, isAvg);
                decimal amplitude = (quote.ExCenter.Equals("HOSE")) ? 0.05m : 0.07m;

                if (isDiscount)
                    stockvalue += item.Ref * item.Quantity * item.AllowRate * 1000;
                else
                    stockvalue += item.Ref * item.Quantity * 1000;
            }

            return stockvalue;
        }

        private List<StocksData> ConvertToStocksUI(List<TradingResultUI> list, int T, bool isCountSettlement, bool isAvg)
        {
            List<StocksData> holding = new List<StocksData>();
            DALclient client = new DALclient();
            MortgageMornitorDAL dal = new MortgageMornitorDAL();
            decimal amplitude = 0;
            foreach (TradingResultUI result in list)
            {
                QuoteDataUI quote = client.getQuoteAvg(result.Symbol, isAvg);

                if (quote != null)
                {
                    decimal rate = dal.getLoanRate(DateTime.Today, result.Symbol);
                    decimal refPrice = quote.Ref;
                    if (isCountSettlement)
                    {
                        //amplitude = (quote.ExCenter.Equals("HOSE")) ? 0.05m : 0.07m;
                        if (quote.ExCenter.Equals("HOSE"))
                            amplitude = 0.05m;
                        else if (quote.ExCenter.Equals("HNX"))
                            amplitude = 0.07m;
                        else
                            amplitude = 0.1m;

                        refPrice = estimateFutureValue(quote.Ref, amplitude, T);
                    }
                    holding.Add(new StocksData(quote.Symbol, result.SubQtty, refPrice, T, rate, quote.CompanyName));

                }
            }
            return holding;
        }

        private decimal estimateFutureValue(decimal Value, decimal amplitide, int T)
        {
            decimal price = Value;
            for (int i = 0; i < T; i++)
            {
                price = price * (1 - amplitide);
            }
            return price;
        }

        private void ClearControls(Control topControl)
        {
            // Ignore the control unless it is a text box.
            if (topControl.GetType() == typeof(TextBox))
            {
                topControl.Text = "";
            }
            else
            {
                // Process controls recursively.
                // This is required if controls contain other controls
                // (for example, if you use panels, group boxes, or other
                // container controls).
                foreach (Control childControl in topControl.Controls)
                {
                    ClearControls(childControl);
                }
            }
        }

        private void UpdateAssetUI(AssetUI asset)
        {

            List<DateTime> backdate = client.getBackDate();
            bool isClearing = client.isClearingDone();

            grvTodayOrders.DataSource = asset.T0TradingHist;
            if (asset.T0TradingHist.Count > 0)
                setOrderSummaryGridLayout(grvTodayOrders);

            SendStocksUIToGrid(grvAccountT0, asset.T0);
            SendStocksUIToGrid(grvAccountT1, asset.T1);
            SendStocksUIToGrid(grvAccountT2, asset.T2);
            SendStocksUIToGrid(grvAccountT3, asset.T3);

            lblT1BoughtStockValue.Text = asset.T1BoughtStockValue.ToString("N0");
            lblT2BoughtStockValue.Text = asset.T2BoughtStockValue.ToString("N0");
            lblT3BoughtStockValue.Text = asset.T3BoughtStockValue.ToString("N0");

            //lblSoldAmount.Text = asset.SoldAmount.ToString("N0");
            //lblBoughtValue.Text = asset.BoughtAmount.ToString("N0");

            lblPorfolioTradingStockValue.Text = asset.PorfolioTradingStockValue.ToString("N0");

            lblTradingAmount.Text = asset.TradingAmount.ToString("N0");
            lblNettingAmount.Text = asset.NettingAmount.ToString("N0");
            lblBlockAmount.Text = asset.BlockAmount.ToString("N0");
            lblPreLoanAmount.Text = asset.PreLoan.ToString("N0");

            lblStockValue.Text = asset.StockAmount.ToString("N0");
            lblCashAmount.Text = asset.CashAmount.ToString("N0");
            lblAssetAmount.Text = asset.AssetAmount.ToString("N0");

            Filter flt = new Filter();
            decimal blocking = flt.getSpentAmount(asset.T0TradingHist);
            lblBoughtValue.Text = blocking.ToString("N0");
            lblT2Deposit.Text = asset.TotalT2Needed.ToString("N0");
            lblCashNeeded.Text = asset.TotalCashNeeded.ToString("N0");


        }

        private void UpdateUIWithAssignAccount(string accountNo, int pos)
        {
            Button mainAccount = new Button();
            mainAccount.Width = 80;
            mainAccount.Location = new Point(pos * 80 + 85, 17);
            mainAccount.Text = accountNo;
            mainAccount.Click += new EventHandler(UpdateInfo);
            grpAccountList.Controls.Add(mainAccount);
        }

        private void chkIsDiscount_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void txtAccountNo_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyValue.Equals(13))
                btnExecute_Click(sender, e);
        }


    }
}
